package io.renren.socket.client.test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.renren.htby.utils.SocketUtils;
import io.renren.modules.iotp.entity.IOTPBean;
import io.renren.modules.iotp.entity.IOTPBody;
import io.renren.modules.iotp.utils.Code;
import io.renren.modules.iotp.utils.IotpBodyUtils;



/**
 * 2018-06-11  的备份
 */
/**
 * 向IOTS 端 发送 配置的连接
 * 
 * @author lfy.xys
 * @date 2018年5月22日
 *
 */
public class IotsConfigConnClientRunnable_2018_06_11 implements Runnable {

	private static Logger logger = LoggerFactory.getLogger(IotsConfigConnClientRunnable_2018_06_11.class);

	private String ip;
	private int port;
	private List<byte[]> sendMsg;
	/*发送数据缓冲区*/
	
//	private byte[] sendMsg;// 发送的消息
	private ByteBuffer rBuffer = ByteBuffer.allocate(8354);
	private int count = 0;

	public IotsConfigConnClientRunnable_2018_06_11(String ip, int port, List<byte[]> sendMsg) {
		this.ip = ip;
		this.port = port;
		this.sendMsg = sendMsg;
	}
	
	SocketChannel client = null;

	public void run() {
		try {
			logger.info(ip + ":" + port);
			InetSocketAddress SERVER = new InetSocketAddress(ip, port);
			SocketChannel socketChannel = SocketChannel.open();
			socketChannel.configureBlocking(false);
			Selector selector = Selector.open();
			socketChannel.register(selector, SelectionKey.OP_CONNECT);
			socketChannel.connect(SERVER);
			

			boolean flag = true;
			
			while (flag) {
				selector.select();
				Set<SelectionKey> keySet = selector.selectedKeys();
				for (final SelectionKey selectionKey : keySet) {
					if (selectionKey.isConnectable()) {
						client = (SocketChannel) selectionKey.channel();
						if (client.isConnectionPending()) {
							try {
								client.finishConnect();
							} catch (Exception e) {
								client.close();
//								reconnect();
							}
							logger.info("connect success ! sendMsg : {}", sendMsg.toString());
							// 发送数据
							int i = 0;
							for (byte[] bs : sendMsg) {
								// 循环发送 socket发送
								// 此业务 不会出现 超长度问题
//								System.out.println(i++ + " :" + Arrays.toString(bs));
								System.out.println(i++ + " :" + bs.length);
								client.write(ByteBuffer.wrap(bs));
							}
						}
						client.register(selector, SelectionKey.OP_READ);
					} else if (selectionKey.isReadable()) {
						boolean failure = true;
						client = (SocketChannel) selectionKey.channel();
						rBuffer.clear();
						try {
							count = client.read(rBuffer);
							logger.info("count:" + count);
							failure = false;
						} catch (Exception e) {
							logger.info("断开连接");
							// e.printStackTrace();
						}

						if (count <= 0 || failure) {
							selectionKey.cancel(); // Some JDK implementations run into an infinite loop without this.
							logger.info("服务端关闭");
							flag = false;
							break;
						} else {
							// 重新读取 指定长度的数据。 否则获取的是创建的缓冲区长度，末尾会被补0。
							rBuffer.clear();
							byte[] bytes = new byte[count];
							rBuffer.get(bytes, 0, bytes.length);
							// client = (SocketChannel) selectionKey.channel();
							client.register(selector, SelectionKey.OP_READ);

							IotpBodyUtils ibu = new IotpBodyUtils();
							IOTPBean iotpBean = ibu.toIotpBean(bytes);
							IOTPBody body = iotpBean.getBody();
							logger.info("body:" + body.toString());
							//获得协议体
							List<String> list = body.getBodyList();
							String resultMsg = list.toString();
							logger.info("接收到结果：{}",resultMsg);
							
							// 关闭 当前socket连接
							flag = false;
							break;
						}
					}
				}
				keySet.clear();
			}

		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(client!=null) {
				try {
					rBuffer.clear();
					client.close();
					logger.info("关闭 {}:{} 的连接", ip, port);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 服务端连接不上，客户端断线重连
	 * 
	 * @author lfy.xys
	 * @date 2018年5月30日
	 *
	 */
	public void reconnect() {
		logger.info("服务端连接失败，{}ms后进行重连...", SocketUtils.NIO_RECONNECT_INTERVAL_TIME);
		try {
			Thread.sleep(SocketUtils.NIO_RECONNECT_INTERVAL_TIME);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		this.run();
	}


}
